home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #3 / Amiga Plus CD - 1997 - No. 03.iso / pd / programmierung / vbcc / regs.c < prev    next >
C/C++ Source or Header  |  1997-03-01  |  42KB  |  1,022 lines

  1. /*  $VER: vbcc (regs.c) V0.4    */
  2. /*  Registerzuteilung           */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. #ifndef NO_OPTIMIZER
  9.  
  10. int (*savings)[MAXR+1],regu[MAXR+1];
  11. int *rvlist;
  12.  
  13. int cmp_savings(const void *v1,const void *v2)
  14. /*  Vergleichsfkt, um rvlist nach savings zu sortieren  */
  15. {
  16.     return savings[*(int *)v2][0]-savings[*(int *)v1][0];
  17. }
  18. int entry_load(struct flowgraph *fg,int i)
  19. /*  Testet, ob die Variable in Register i am Anfang von Block fg geladen    */
  20. /*  werden muss, d.h. ein Vorgaenger sie nicht im selben Register hat.      */
  21. {
  22.     struct flowlist *lp;
  23.     lp=fg->in;
  24.     /*  Parameter am Anfang laden?  */
  25. /*    if(fg==fg1&&!zlleq(l2zl(0L),fg->regv[i]->offset)) return(1);*/
  26.     if(!lp) return(1);
  27.     while(lp){
  28.         if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]&&BTST(lp->graph->av_out,fg->regv[i]->index)) return(1);
  29.         lp=lp->next;
  30.     }
  31.     return(0);
  32. }
  33.  
  34. int exit_save(struct flowgraph *fg,int i)
  35. /*  Testet, ob die Variable in Register i am Ende von Block fg gespeichert  */
  36. /*  werden muss, d.h. der Vorgaenger eines Nachfolgers nicht dieselbe       */
  37. /*  Variable im selben Register hat.                                        */
  38. {
  39.     struct flowlist *lp;
  40.     if((fg->normalout&&(!fg->end||fg->end->code!=BRA))&&BTST(fg->normalout->av_in,fg->regv[i]->index)){
  41.         if(fg->normalout->regv[i]!=fg->regv[i]) return(1);
  42.         lp=fg->normalout->in;
  43.         while(lp){
  44.             if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
  45.             lp=lp->next;
  46.         }
  47.     }
  48.     if(fg->branchout&&BTST(fg->branchout->av_in,fg->regv[i]->index)){
  49.         if(fg->branchout->regv[i]!=fg->regv[i]) return(1);
  50.         lp=fg->branchout->in;
  51.         while(lp){
  52.             if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
  53.             lp=lp->next;
  54.         }
  55.     }
  56.     return(0);
  57. }
  58. void load_reg_parms(struct flowgraph *fg)
  59. /*  Laedt Registerparameter, falls noetig.                              */
  60. {
  61.     int i; struct Var *v;
  62.     for(i=0;i<vcount-rcount;i++){
  63.         v=vilist[i];
  64.         if((v->flags®PARM)&&fg->regv[v->reg]!=v&&(BTST(fg->av_in,i)||(v->flags&USEDASADR))){
  65.             struct IC *new; int j;
  66.             insert_allocreg(fg,0,FREEREG,v->reg);
  67.             new=mymalloc(ICS);
  68.             new->line=0;
  69.             new->file=0;
  70.             new->code=ASSIGN;
  71.             new->typf=v->vtyp->flags;
  72.             new->q1.flags=REG;
  73.             new->q1.reg=v->reg;
  74.             new->q2.flags=0;
  75.             new->q2.val.vlong=szof(v->vtyp);
  76.             new->z.flags=VAR;
  77.             new->z.val.vlong=l2zl(0L);
  78.             new->z.v=v;
  79.             for(j=1;j<=MAXR;j++)
  80.                 if(fg->regv[j]==v){ new->z.flags|=REG;new->z.reg=j;break; }
  81.             new->q1.am=new->q2.am=new->z.am=0;
  82.             new->use_cnt=new->change_cnt=0;
  83.             new->use_list=new->change_list=0;
  84.             insert_IC_fg(fg,0,new);
  85.             insert_allocreg(fg,0,ALLOCREG,v->reg);
  86.             if(new->z.flags®){
  87.                 /*  ALLOCREG verschieben    */
  88.                 struct IC *p;
  89.                 insert_allocreg(fg,0,ALLOCREG,new->z.reg);
  90.                 for(p=new->next;p;p=p->next){
  91.                     if(p->code==ALLOCREG&&p->q1.reg==new->z.reg){
  92.                         remove_IC_fg(fg,p);
  93.                         break;
  94.                     }
  95.                 }
  96.                 if(!p) ierror(0);
  97.             }
  98.             v->offset=l2zl(0);
  99.         }
  100.     }
  101. }
  102. void insert_regs(struct flowgraph *fg1)
  103. /*  Fuegt Registervariablen in die ICs ein.                             */
  104. {
  105.     int i;struct IC *p,*lic=0,*new;struct flowgraph *lfg=0,*fg;
  106.     if(DEBUG&9216) printf("inserting register variables\n");
  107.     fg=fg1;
  108.     while(fg){
  109.         if(DEBUG&8192) printf("block %d:\n",fg->index);
  110.         p=fg->start;
  111.         while(p){
  112.             for(i=1;i<=MAXR;i++){
  113.                 if(!fg->regv[i]) continue;
  114.                 if(p->code==ALLOCREG&&p->q1.reg==i) ierror(0);
  115.                 if((p->q1.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q1.v==fg->regv[i]){
  116.                     p->q1.flags|=REG;
  117.                     p->q1.reg=i;
  118.                 }
  119.                 if((p->q2.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q2.v==fg->regv[i]){
  120.                     p->q2.flags|=REG;
  121.                     p->q2.reg=i;
  122.                 }
  123.                 if((p->z.flags&(VAR|DONTREGISTERIZE))==VAR&&p->z.v==fg->regv[i]){
  124.                     p->z.flags|=REG;
  125.                     p->z.reg=i;
  126.                 }
  127.             }
  128.             if(DEBUG&8192) pric2(stdout,p);
  129.             if(p==fg->end) break;
  130.             p=p->next;
  131.         }
  132.         if(fg->start&&fg->start->code==LABEL) lic=fg->start;
  133.         for(i=1;i<=MAXR;i++){
  134.             if(fg->regv[i]){
  135.                 if(DEBUG&8192){
  136.                     printf("(%s),%ld assigned to %s\n",fg->regv[i]->identifier,zl2l(fg->regv[i]->offset),regnames[i]);
  137.                     if(BTST(fg->av_in,fg->regv[i]->index)) printf("active at the start of block\n");
  138.                     if(BTST(fg->av_out,fg->regv[i]->index)) printf("active at the end of block\n");
  139.                 }
  140.  
  141.                 if(BTST(fg->av_out,fg->regv[i]->index)){
  142.                 /*  Variable beim Austritt aktiv?   */
  143.                     if(exit_save(fg,i)){
  144.                         struct IC *tp;
  145.                         if(DEBUG&8192) printf("\thave to save it at end of block\n");
  146.                         new=mymalloc(ICS);
  147.                         new->line=0;
  148.                         new->file=0;
  149.                         new->code=ASSIGN;
  150.                         new->typf=fg->regv[i]->vtyp->flags;
  151.                         /*  cc  */
  152.                         if(new->typf==0) ierror(0);
  153.                         new->q1.flags=VAR|REG;
  154.                         new->q1.val.vlong=l2zl(0L);
  155.                         new->q1.v=fg->regv[i];
  156.                         new->q1.reg=i;
  157.                         new->q2.flags=0;
  158.                         new->q2.val.vlong=szof(fg->regv[i]->vtyp);
  159.                         new->z.flags=VAR|DONTREGISTERIZE;
  160.                         new->z.val.vlong=l2zl(0L);
  161.                         new->z.v=fg->regv[i];
  162.                         new->q1.am=new->q2.am=new->z.am=0;
  163.                         new->use_cnt=new->change_cnt=0;
  164.                         new->use_list=new->change_list=0;
  165.                         /*  Vor FREEREGs und evtl. Branch+COMPARE/TEST setzen   */
  166.                         if(fg->end){
  167.                             tp=fg->end;
  168.                             while(tp!=fg->start&&tp->code==FREEREG)
  169.                                 tp=tp->prev;
  170.                             if(tp&&tp->code>=BEQ&&tp->code<=BRA){
  171.                                 if(tp->code<BRA){
  172.                                     int c;
  173.                                     do{
  174.                                         tp=tp->prev;
  175.                                         c=tp->code;
  176.                                         if(c!=FREEREG&&c!=COMPARE&&c!=TEST) ierror(0);
  177.                                     }while(c!=COMPARE&&c!=TEST);
  178.                                 }
  179.                                 tp=tp->prev;
  180.                             }
  181.                         }else tp=lic;
  182.                         insert_IC_fg(fg,tp,new);
  183.                     }
  184.                 }
  185.                 if(BTST(fg->av_in,fg->regv[i]->index)){
  186.                     if(entry_load(fg,i)&&(fg!=fg1||!(fg->regv[i]->flags®PARM))){
  187.                         if(DEBUG&8192) printf("\thave to load it at start of block\n");
  188.  
  189.                         new=mymalloc(ICS);
  190.                         new->line=0;
  191.                         new->file=0;
  192.                         new->code=ASSIGN;
  193.                         new->typf=fg->regv[i]->vtyp->flags;
  194.                         /*  cc  */
  195.                         if(new->typf==0) ierror(0);
  196.                         new->q1.flags=VAR|DONTREGISTERIZE;
  197.                         new->q1.val.vlong=l2zl(0L);
  198.                         new->q1.v=fg->regv[i];
  199.                         new->q2.flags=0;
  200.                         new->q2.val.vlong=szof(fg->regv[i]->vtyp);
  201.                         new->z.flags=VAR|REG;
  202.                         new->z.val.vlong=l2zl(0L);
  203.                         new->z.v=fg->regv[i];
  204.                         new->z.reg=i;
  205.                         new->q1.am=new->q2.am=new->z.am=0;
  206.                         new->use_cnt=new->change_cnt=0;
  207.                         new->use_list=new->change_list=0;
  208.                         insert_IC_fg(fg,lic,new);
  209.                     }
  210.                 }
  211.                 if(!lfg||!lfg->regv[i]) insert_allocreg(fg,lic,ALLOCREG,i);
  212.                 if(!fg->normalout||!fg->normalout->regv[i])
  213.                     insert_allocreg(fg,fg->end?fg->end:lic,FREEREG,i);
  214.             }
  215.         }
  216.         if(fg->end) lic=fg->end;
  217.         lfg=fg;
  218.         fg=fg->normalout;
  219.     }
  220.     load_reg_parms(fg1);
  221. }
  222.  
  223. void do_loop_regs(struct flowgraph *start,struct flowgraph *end)
  224. /*  Macht die Variablenzuweisung in Schleife start-end.                 */
  225. /*  Wenn end==0 Registerzuweisung fuer die ganze Funktion, ansonsten    */
  226. /*  fuer die Schleife, die zum Header start gehoert.                    */
  227. {
  228.     struct flowgraph *g;
  229.     int i,r;
  230.     struct Var *lregs[MAXR+1]={0};
  231.     unsigned char rused[(MAXR+CHAR_BIT)/CHAR_BIT];
  232.     /*  Berechnen, wieviel ungefaehr eingespart wird, wenn eine Variable    */
  233.     /*  fuer diese Schleife in einem best. Register gehalten wird.          */
  234.     /*  Die savings in einer Schleife werden multipliziert, um das          */
  235.     /*  Laden/Speichern ausserhalb der Schleife geringer zu wichten.        */
  236. /*    if(end&&(!g->normalout||!g->normalout->loopend||g->normalout->loopend->normalout->index!=-2)) ierror(0);*/
  237.     /*  alle auf 0  */
  238.     for(i=0;i<vcount-rcount;i++){
  239.         for(r=1;r<=MAXR;r++){
  240.             savings[i][r]=0;
  241.         }
  242.     }
  243.     if(end){
  244.         struct Var *v;
  245.         /*  Evtl. Kosten fuers Laden/Speichern beim Ein-/Austritt in die    */
  246.         /*  Schleife.                                                       */
  247.         end=start->normalout->loopend;
  248.         g=end->normalout;
  249.         if(DEBUG&9216) printf("assigning regs to blocks %d to %d\n",start->normalout->index,end->index);
  250.         /*  Werte modifizieren, falls Variable am Anfang/Ende der Schleife  */
  251.         /*  geladen/gespeichert werden muss.                                */
  252.         for(i=0;i<vcount-rcount;i++){
  253.             v=vilist[i];
  254.             if(BTST(start->av_in,i)){
  255.                 for(r=1;r<=MAXR;r++)
  256.                     if(start->regv[r]!=v) savings[i][r]--;
  257.             }
  258.             if(BTST(g->av_out,i)){
  259.                 for(r=1;r<=MAXR;r++)
  260.                     if(g->regv[r]!=v) savings[i][r]--;
  261.             }
  262.         }
  263.         /*  Werte modifizieren, falls eine andere Variable gespeichert oder */
  264.         /*  geladen werden muss. Hmm..stimmt das so?                        */
  265.         for(r=1;r<=MAXR;r++){
  266.             v=start->regv[r];
  267.             if(v&&BTST(start->av_in,v->index)){
  268.                 for(i=0;i<vcount-rcount;i++)
  269.                     if(v->index!=i) savings[i][r]--;
  270.             }
  271.             if(v&&BTST(g->av_out,v->index)){
  272.                 for(i=0;i<vcount-rcount;i++)
  273.                     if(v->index!=i) savings[i][r]--;
  274.             }
  275.         }
  276.         g=start->normalout;
  277.     }else{
  278.         /*  Bei Registervergabe fuer die ganze Funktion muessen alle beim   */
  279.         /*  Eintritt der Funktion aktiven Variablen geladen werden.         */
  280.         if(DEBUG&9216) printf("assigning regs to whole function\n");
  281.         for(i=0;i<vcount-rcount;i++){
  282.             if(BTST(start->av_in,i)){
  283.                 int pr=vilist[i]->reg;
  284.                 for(r=1;r<=MAXR;r++){
  285.                     if(pr==0||!regok(r,vilist[i]->vtyp->flags,0)||regsa[r]){
  286.                         savings[i][r]-=8;
  287.                     }else{
  288.                         if(r==pr) savings[i][r]+=8; else savings[i][r]+=4;
  289.                     }
  290.                 }
  291.             }
  292.         }
  293.         g=start;
  294.     }
  295.     if(DEBUG&9216) printf("calculating approximate savings\n");
  296.  
  297.     for(;g;g=g->normalout){
  298.         struct IC *p;struct Var *v;
  299.         int t,vt;
  300.         if(g->calls>0){
  301.         /*  bei Funktionsaufrufen muessen Scratchregister gespeichert werden */
  302.             for(r=1;r<=MAXR;r++)
  303.                 if(regscratch[r])
  304.                     for(i=0;i<vcount-rcount;i++) savings[i][r]-=g->calls*16;
  305.         }
  306.         /*  Wenn das Register in dem Block benutzt wird, muss man es retten */
  307.         for(r=1;r<=MAXR;r++){
  308.             if(BTST(g->regused,r)){
  309.                 int vi;
  310.                 if(g->regv[r]) vi=g->regv[r]->index; else vi=-1;
  311.                 for(i=0;i<vcount-rcount;i++)
  312.                     if(vi!=i) savings[i][r]-=16;
  313.             }
  314.         }
  315.         for(p=g->start;p;p=p->next){
  316.             if((p->q1.flags&(VAR|VARADR|REG))==VAR){
  317.                 v=p->q1.v;
  318.                 if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  319.                     vt=v->vtyp->flags&31;
  320.                     i=v->index;
  321.                     if(p->q1.flags&DREFOBJ) t=p->typf&31; else t=0;
  322.                     for(r=1;r<=MAXR;r++){
  323.                         if(!regsa[r]&&!BTST(g->regused,r)){
  324.                             /*  extra saving, falls passendes Reg fuer DREF */
  325.                             if(t&®ok(r,vt,t)) savings[i][r]+=8;
  326.                             if(regok(r,vt,0)) savings[i][r]+=8;
  327.                         }
  328.                     }
  329.                 }
  330.             }
  331.             if((p->q2.flags&(VAR|VARADR|REG))==VAR){
  332.                 v=p->q2.v;
  333.                 if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  334.                     vt=v->vtyp->flags&31;
  335.                     i=v->index;
  336.                     if(p->q2.flags&DREFOBJ) t=p->typf&31; else t=0;
  337.                     for(r=1;r<=MAXR;r++){
  338.                         if(!regsa[r]&&!BTST(g->regused,r)){
  339.                             /*  extra saving, falls passendes Reg fuer DREF */
  340.                             if(t&®ok(r,vt,t)) savings[i][r]+=8;
  341.                             if(regok(r,vt,0)) savings[i][r]+=8;
  342.                         }
  343.                     }
  344.                 }
  345.             }
  346.             if((p->z.flags&(VAR|VARADR|REG))==VAR){
  347.                 v=p->z.v;
  348.                 if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  349.                     vt=v->vtyp->flags&31;
  350.                     i=v->index;
  351.                     if(p->z.flags&DREFOBJ) t=p->typf&31; else t=0;
  352.                     for(r=1;r<=MAXR;r++){
  353.                         if(!regsa[r]&&!BTST(g->regused,r)){
  354.                             /*  extra saving, falls passendes Reg fuer DREF */
  355.                             if(t&®ok(r,vt,t)) savings[i][r]+=8;
  356.                             if(regok(r,vt,0)) savings[i][r]+=8;
  357.                         }
  358.                     }
  359.                 }
  360.             }
  361.             if(p==g->end) break;
  362.         }
  363.         if(g==end) break;
  364.     }
  365.     /*  Maximum ermitteln   */
  366.     for(i=0;i<vcount-rcount;i++){
  367.         int m=0;
  368.         for(r=1;r<=MAXR;r++){
  369.             /*  Falls Variable in best. Register muss.  */
  370.             if(r==vilist[i]->reg&&!(vilist[i]->flags®PARM)) savings[i][r]*=4;
  371.             if(savings[i][r]>m) m=savings[i][r];
  372.         }
  373.         savings[i][0]=m;
  374.     }
  375.  
  376.     if(DEBUG&8192){
  377.         for(i=0;i<vcount-rcount;i++){
  378.             printf("(%s),%ld(best=%d):\n",vilist[i]->identifier,zl2l(vilist[i]->offset),savings[i][0]);
  379.             for(r=1;r<=MAXR;r++)
  380.                 printf("%s=%d ",regnames[r],savings[i][r]);
  381.             printf("\n");
  382.         }
  383.     }
  384.     /*  Suchen, welche Variablen/Registerkombination das beste Ergebnis */
  385.     /*  liefert. Nur angenaehert, da sonst wohl zu aufwendig. Simplex?  */
  386.     memset(rused,0,(MAXR+CHAR_BIT)/CHAR_BIT);
  387.     for(i=0;i<vcount-rcount;i++) rvlist[i]=i;
  388.     qsort(rvlist,vcount-rcount,sizeof(*rvlist),cmp_savings);
  389.     for(i=0;i<vcount-rcount;i++){
  390.         int use,m=0,vi;
  391.         vi=rvlist[i];
  392.         if(vilist[vi]->flags&USEDASADR) continue;
  393.         if(DEBUG&8192) printf("%d: (%s),%ld(best=%d)\n",i,vilist[vi]->identifier,zl2l(vilist[vi]->offset),savings[vi][0]);
  394.         for(r=1;r<=MAXR;r++){
  395.             if(!lregs[r]&&savings[vi][r]>m){
  396.                 m=savings[vi][r];
  397.                 use=r;
  398.                 if(m==savings[vi][0]) break;
  399.             }
  400.         }
  401.         if(m>0){
  402.             if(DEBUG&9216) printf("assigned (%s),%ld to %s, saving=%d\n",vilist[vi]->identifier,zl2l(vilist[vi]->offset),regnames[use],m);
  403.             lregs[use]=vilist[vi];
  404.             BSET(rused,use);
  405.         }
  406.     }
  407.     /*  Registervariablen in alle Bloecke der Schleife eintragen    */
  408.     /*  dabei beruecksichtigen, dass sie in manchen Bloecken nicht  */
  409.     /*  in Register kommen koennen, wenn das Register da schon von  */
  410.     /*  local_regs benutzt wird                                     */
  411.     /*  Gegebenenfalls auch in Header/Footer einer Schleife         */
  412.     /*  eintragen.                                                  */
  413.     if(DEBUG&9216) printf("propagate register vars\n");
  414.     for(g=start;g;g=g->normalout){
  415.         for(r=1;r<=MAXR;r++){
  416.             if(lregs[r]&&!BTST(g->regused,r)){
  417.                 /*  Falls Variable schon in anderem Register, loeschen  */
  418.                 for(i=1;i<=MAXR;i++){
  419.                     if(g->regv[i]==lregs[r]) g->regv[i]=0;
  420.                 }
  421.                 g->regv[r]=lregs[r];
  422.             }
  423.         }
  424.         if(end&&g==end->normalout) break;
  425.     }
  426. }
  427. void block_regs(struct flowgraph *fg)
  428. /*  macht die Variablenzuweisung fuer einzelne Bloecke  */
  429. {
  430.     struct flowgraph *g,**fgp;
  431.     int i,r,changed,fgz;
  432.     if(DEBUG&9216) printf("block_regs\n");
  433.  
  434.     savings=mymalloc((vcount-rcount)*sizeof(*savings));
  435.     rvlist=mymalloc((vcount-rcount)*sizeof(*rvlist));
  436.  
  437.     /*  Array auf Bloecke im Flussgraphen mangels doppelter Verkettung  */
  438.     fgp=mymalloc(basic_blocks*sizeof(*fgp));
  439.     g=fg;fgz=0;
  440.     while(g){
  441.         fgp[fgz]=g;fgz++;
  442.         g=g->normalout;
  443.     }
  444.     if(fgz>basic_blocks) ierror(0); else basic_blocks=fgz;
  445.     /*  alle auf 0  */
  446.     do{
  447.         changed=0;
  448.         if(DEBUG&9216) printf("block_regs pass\n");
  449.         for(fgz=basic_blocks-1;fgz>=0;fgz--){
  450.             struct IC *p;struct Var *v;struct flowlist *lp;
  451.             int t,vt;
  452.             g=fgp[fgz];
  453.             if(DEBUG&8192) printf("assigning regs to block %d\n",g->index);
  454.             /*  berechnen, wieviel ungefaehr eingespart wird, wenn eine Variable    */
  455.             /*  fuer diesen Block in einem best. Register gehalten wird             */
  456.             if(DEBUG&8192) printf("calculating approximate savings\n");
  457.  
  458.             for(i=0;i<vcount-rcount;i++){
  459.                 for(r=1;r<=MAXR;r++){
  460.                     if(!g->regv[r]||g->regv[r]->index!=i){
  461.                         int w=0;
  462.                         /*  Variable muss evtl. geladen/gespeichert werden  */
  463.                         if(BTST(g->av_in,i)) w--;
  464.                         if(BTST(g->av_out,i)) w--;
  465.                         savings[i][r]=w;
  466.                     }
  467.                 }
  468.             }
  469.             if(g->calls>0){
  470.             /*  bei Funktionsaufrufen muessen Scratchregister gespeichert werden */
  471.                 for(r=1;r<=MAXR;r++)
  472.                     if(regscratch[r])
  473.                         for(i=0;i<vcount-rcount;i++) savings[i][r]-=g->calls*2;
  474.             }
  475.             /*  Wenn Vorgaenger/Nachfolger selbe Variable im selben */
  476.             /*  Register hat, entfaellt Laden/Speichern in diesem   */
  477.             /*  Block und vermutlich auch im Vorgaenger/Nachfolger  */
  478.             /*  nicht immer, aber naeherungsweise...                */
  479.             lp=g->in;
  480.             while(lp){
  481.                 if(lp->graph){
  482.                     for(r=1;r<=MAXR;r++){
  483.                         if(lp->graph->regv[r]&&BTST(g->av_in,lp->graph->regv[r]->index)) savings[lp->graph->regv[r]->index][r]+=2;
  484.                     }
  485.                 }
  486.                 lp=lp->next;
  487.             }
  488.             if(g->branchout){
  489.                 for(r=1;r<=MAXR;r++){
  490.                     if(g->branchout->regv[r]&&BTST(g->av_out,g->branchout->regv[r]->index)) savings[g->branchout->regv[r]->index][r]+=2;
  491.                 }
  492.             }
  493.             if(g->normalout&&(!g->normalout->end||g->normalout->end->code!=BRA)){
  494.                 for(r=1;r<=MAXR;r++){
  495.                     if(g->normalout->regv[r]&&BTST(g->av_out,g->normalout->regv[r]->index)) savings[g->normalout->regv[r]->index][r]+=2;
  496.                 }
  497.             }
  498.  
  499.             p=g->start;
  500.             while(p){
  501.                 if((p->q1.flags&(VAR|VARADR|REG))==VAR){
  502.                     v=p->q1.v;
  503.                     if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  504.                         vt=v->vtyp->flags&31;
  505.                         i=v->index;
  506.                         if(p->q1.flags&DREFOBJ) t=p->typf&31; else t=0;
  507.                         for(r=1;r<=MAXR;r++){
  508.                             if(!regsa[r]&&!BTST(g->regused,r)){
  509.                                 /*  extra saving, falls passendes Reg fuer DREF */
  510.                                 if(t&®ok(r,vt,t)) savings[i][r]++;
  511.                                 if(regok(r,vt,0)) savings[i][r]++;
  512.                             }
  513.                         }
  514.                     }
  515.                 }
  516.                 if((p->q2.flags&(VAR|VARADR|REG))==VAR){
  517.                     v=p->q2.v;
  518.                     if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  519.                         vt=v->vtyp->flags&31;
  520.                         i=v->index;
  521.                         if(p->q2.flags&DREFOBJ) t=p->typf&31; else t=0;
  522.                         for(r=1;r<=MAXR;r++){
  523.                             if(!regsa[r]&&!BTST(g->regused,r)){
  524.                                 /*  extra saving, falls passendes Reg fuer DREF */
  525.                                 if(t&®ok(r,vt,t)) savings[i][r]++;
  526.                                 if(regok(r,vt,0)) savings[i][r]++;
  527.                             }
  528.                         }
  529.                     }
  530.                 }
  531.                 if((p->z.flags&(VAR|VARADR|REG))==VAR){
  532.                     v=p->z.v;
  533.                     if((v->storage_class==AUTO||v->storage_class==REGISTER)&&!(v->flags&USEDASADR)){
  534.                         vt=v->vtyp->flags&31;
  535.                         i=v->index;
  536.                         if(p->z.flags&DREFOBJ) t=p->typf&31; else t=0;
  537.                         for(r=1;r<=MAXR;r++){
  538.                             if(!regsa[r]&&!BTST(g->regused,r)){
  539.                                 /*  extra saving, falls passendes Reg fuer DREF */
  540.                                 if(t&®ok(r,vt,t)) savings[i][r]++;
  541.                                 if(regok(r,vt,0)) savings[i][r]++;
  542.                             }
  543.                         }
  544.                     }
  545.                 }
  546.                 if(p==g->end) break;
  547.                 p=p->next;
  548.             }
  549.             /*  moegliche Kandidaten suchen; muss nicht immer die beste */
  550.             /*  Kombination finden, sollte aber bei lokaler Vergabe     */
  551.             /*  selten einen Unterschied machen                         */
  552.             for(r=1;r<=MAXR;r++){
  553.                 if(g->regv[r]||BTST(g->regused,r)) continue;
  554.                 for(i=0;i<vcount-rcount;i++){
  555.                     if(savings[i][r]>0){
  556.                         int flag;struct Var *v=vilist[i];
  557.                         /*  Variable schon in anderem Register? */
  558.                         for(flag=1;flag<=MAXR;flag++)
  559.                             if(g->regv[flag]==v){flag=-1;break;}
  560.                         if(flag>0){
  561.                             if(DEBUG&9216) printf("assigned (%s),%ld to %s; saving=%d\n",vilist[i]->identifier,zl2l(vilist[i]->offset),regnames[r],savings[i][r]);
  562.                             g->regv[r]=vilist[i];
  563.                             changed=1;
  564.                             break;
  565.                         }
  566.                     }
  567.                 }
  568.             }
  569.         }
  570.     }while(changed);
  571.     /*  jetzt nochmal globale Register vergeben */
  572. /*    do_loop_regs(fgp[0],fgp[basic_blocks-1]);*/
  573.  
  574.     free(fgp);
  575.     free(rvlist);
  576.     free(savings);
  577. }
  578.  
  579. void loop_regs(struct flowgraph *fg)
  580. /*  weist Variablen in Schleifen Register zu    */
  581. {
  582.     struct flowgraph *g;
  583.     if(DEBUG&9216) printf("assigning regs to function\n");
  584.     savings=mymalloc((vcount-rcount)*sizeof(*savings));
  585.     rvlist=mymalloc((vcount-rcount)*sizeof(*rvlist));
  586.     do_loop_regs(fg,0);
  587.     if(DEBUG&9216) printf("assigning regs in loops\n");
  588.     for(g=fg;g;g=g->normalout){
  589.         if(g->index==-1) do_loop_regs(g,g);
  590.     }
  591.     free(rvlist);
  592.     free(savings);
  593. }
  594. void insert_allocreg(struct flowgraph *fg,struct IC *p,int code,int reg)
  595. /*  Fuegt ein ALLOCREG/FREEREG (in code) hinter p ein - bei p==0 in */
  596. /*  first_ic.                                                       */
  597. {
  598.     struct IC *new=mymalloc(ICS);
  599.     new->line=0;
  600.     new->file=0;
  601.     BSET(fg->regused,reg);
  602.     regused[reg]=1;
  603.     new->code=code;
  604.     new->typf=0;
  605.     new->q1.am=new->q2.am=new->z.am=0;
  606.     new->q1.flags=REG;
  607.     new->q1.reg=reg;
  608.     new->q2.flags=new->z.flags=0;
  609.     new->use_cnt=new->change_cnt=0;
  610.     new->use_list=new->change_list=0;
  611.     insert_IC_fg(fg,p,new);
  612. }
  613.  
  614. struct Var *lregv[MAXR+1];
  615. struct flowgraph *lfg;
  616.  
  617. void free_hreg(struct flowgraph *fg,struct IC *p,int reg,int mustr)
  618. /*  Macht das Register reg frei, damit es als lokale Variable im IC p   */
  619. /*  zur Verfuegung steht. Wenn mustr!=0, muss das Register unbedingt    */
  620. /*  freigemacht werden, ansonsten kann davon abgesehen werden.          */
  621. {
  622.     struct IC *m,*first;struct Var *v;
  623.     int preg[MAXR+1]={0},calls=0,rreg,i;
  624.     first=0; v=lregv[reg];
  625.     if(!v) ierror(0);
  626.     if(DEBUG&8192) printf("free_hreg %s,%s,%d\n",regnames[reg],v->identifier,mustr);
  627.     if(v->reg) error(218,regnames[reg]);
  628.     for(m=p;m;m=m->next){
  629.         if(m->code==CALL) calls++;
  630.         if(m->code==ALLOCREG){
  631.             preg[m->q1.reg]=1;
  632.             if(m->q1.reg==reg) ierror(0);
  633.         }
  634.         if(m->code==FREEREG){
  635.             preg[m->q1.reg]=1;
  636.             if(m->q1.reg==reg) break;
  637.         }
  638.         if(!USEQ2ASZ){
  639.             if((m->q2.flags&VAR)&&m->q2.v==v&&(m->z.flags&(REG|DREFOBJ))==REG&&
  640.                (!(m->z.flags&VAR)||m->z.v!=v))
  641.                 preg[m->z.reg]=1;
  642.         }
  643.         if(((m->q1.flags&VAR)&&m->q1.v==v)||
  644.            ((m->q2.flags&VAR)&&m->q2.v==v)||
  645.            ((m->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&m->z.v==v))
  646.             first=m;
  647. /*        if((m->z.flags&(REG|DREFOBJ))==REG&&m->z.reg==reg) break;*/
  648.     }
  649.     if(!first) {pric(stdout,p);ierror(0);}
  650.     for(rreg=0,i=1;i<=MAXR;i++){
  651.         if(preg[i]||regu[i]||regsa[i]||!regok(i,v->vtyp->flags,0)) continue;
  652.         if(calls==0&®scratch[i]){rreg=i;break;}
  653.         if(calls>0&&!regscratch[i]){rreg=i;break;}
  654.         if(calls==0&&mustr) rreg=i;
  655.     }
  656.     if(!rreg&&!mustr) return;
  657.     for(m=p;m!=first->next;m=m->next){
  658.         if((m->q1.flags&VAR)&&m->q1.v==v)
  659.             {if(!rreg) m->q1.flags&=~REG; else m->q1.reg=rreg;}
  660.         if((m->q2.flags&VAR)&&m->q2.v==v)
  661.             {if(!rreg) m->q2.flags&=~REG; else m->q2.reg=rreg;}
  662.         if((m->z.flags&VAR)&&m->z.v==v)
  663.             {if(!rreg) m->z.flags&=~REG; else m->z.reg=rreg;}
  664.     }
  665.     if(rreg){lregv[rreg]=lregv[reg];regused[rreg]=1;regu[rreg]=1;BSET(fg->regused,rreg);}
  666.     lregv[reg]=0;regu[reg]=0;
  667.  
  668.     for(m=first->next;m&&m->code==FREEREG;m=m->next){
  669.         if(m->q1.reg==reg){
  670.             if(!rreg) remove_IC_fg(fg,m); else m->q1.reg=rreg;
  671.             if(rreg) insert_allocreg(fg,first,FREEREG,rreg);
  672.             return;
  673.         }
  674.     }
  675.     insert_allocreg(fg,first->prev,ALLOCREG,reg);
  676.     if(rreg) insert_allocreg(fg,first,FREEREG,rreg);
  677. }
  678. int replace_local_reg(struct obj *o)
  679. /*  tested, ob o eine Scratch-Variable ist und ersetzt sie gegebenenfalls   */
  680. {
  681.     int i;struct Var *v;
  682.     if((o->flags&(VAR|REG|VARADR))==VAR){
  683.         v=o->v;i=v->index;
  684.         if(BTST(lfg->av_kill,i)&&!BTST(lfg->av_out,i)){
  685.             for(i=1;i<=MAXR;i++){
  686.                 if(lregv[i]==v){
  687.                     o->flags|=(REG|SCRATCH);
  688. /*                    o->flags&=~VAR;*/
  689.                     o->reg=i;
  690.                     return(i);
  691.                 }
  692.             }
  693.         }
  694.     }
  695.     return(0);
  696. }
  697. void local_regs(struct flowgraph *fg)
  698. /*  versucht Variablen, die nur innerhalb eines Basic Blocks benutzt    */
  699. /*  werden (kill==true und out==false), Register zuzuweisen.            */
  700. {
  701.     struct IC *p;
  702.     int i,t,r,nr,mustalloc;
  703.     if(DEBUG&9216) printf("assigning temporary variables to registers\n");
  704.     lfg=fg;
  705.     while(lfg){
  706.         if(DEBUG&1024) printf("block %d\n",lfg->index);
  707.         for(i=1;i<=MAXR;i++){lregv[i]=0; regu[i]=regsa[i]; lfg->regv[i]=0;}
  708.         memset(&lfg->regused,0,(MAXR+CHAR_BIT)/CHAR_BIT);
  709.         lfg->calls=0;
  710.         p=lfg->end;
  711.         while(p){
  712.             i=replace_local_reg(&p->z);
  713.             if(i&&!(p->z.flags&DREFOBJ)){
  714.                 lregv[i]=0;regu[i]--;
  715.                 nr=i;mustalloc=1;
  716.                 if(DEBUG&8192) printf("regu[%s] decremented to %d\n",regnames[i],regu[i]);
  717.             }else nr=0;
  718.             if(p->code!=ADDRESS){
  719.                 if(replace_local_reg(&p->q1)==nr) mustalloc=0;
  720.                 if(replace_local_reg(&p->q2)==nr) mustalloc=0;
  721.             }
  722.             /*  hier wegen USEQ2ASZ aufpassen; kommutative ICs sollten so   */
  723.             /*  angeordnet werden, dass ein evtl. Register rechts steht     */
  724.             if((p->q2.flags&(VAR|REG|VARADR))==VAR&&!(p->q2.v->flags&USEDASADR)&&!(p->q2.v->vtyp->flags&VOLATILE)&&(p->q2.v->storage_class==AUTO||p->q2.v->storage_class==REGISTER)){
  725.                 i=p->q2.v->index;
  726.                 if(BTST(lfg->av_kill,i)&&!BTST(lfg->av_out,i)){
  727.                     t=p->q2.v->vtyp->flags;
  728.                     if(USEQ2ASZ&&nr&®ok(nr,t,0)&&(!(p->q2.flags&DREFOBJ)||regok(nr,t,p->typf))) r=nr; else r=0;
  729.                     if(p->q2.v->reg){ r=p->q2.v->reg;if(regu[r]) free_hreg(lfg,p,r,1);}
  730.                     for(i=0;r==0&&i<=MAXR;i++){
  731.                         if(!regu[i]&&!regsa[i]&®ok(i,t,0)&&(USEQ2ASZ||i!=nr)) {r=i;break;}
  732.                     }
  733.                     if(r){
  734.                         if(r!=nr) insert_allocreg(lfg,p,FREEREG,r);
  735.                             else mustalloc=0;
  736.                         lregv[r]=p->q2.v;regused[r]=regu[r]=1;
  737.                         if(replace_local_reg(&p->q2)!=r) ierror(0);
  738.                         replace_local_reg(&p->q1);
  739.                         replace_local_reg(&p->z);
  740.                         if((DEBUG&9216)&&*p->q2.v->identifier) printf("temporary <%s> assigned to %s\n",p->q2.v->identifier,regnames[r]);
  741.                         if(DEBUG&8192) printf("temporary <%s> assigned to %s\n",p->q2.v->identifier,regnames[r]);
  742.                     }
  743.                 }
  744.             }
  745.             if((p->z.flags&(VAR|REG|DREFOBJ))==(VAR|DREFOBJ)&&!(p->z.v->flags&USEDASADR)&&!(p->z.v->vtyp->flags&VOLATILE)&&(p->z.v->storage_class==AUTO||p->z.v->storage_class==REGISTER)){
  746.                 i=p->z.v->index;
  747.                 if(BTST(lfg->av_kill,i)&&!BTST(lfg->av_out,i)){
  748.                     r=0;
  749.                     if(p->z.v->reg){ r=p->z.v->reg;if(regu[r]) free_hreg(lfg,p,r,1);}
  750.                     for(i=0,t=p->z.v->vtyp->flags;i<=MAXR;i++){
  751.                         if(!regu[i]&&!regsa[i]&®ok(i,t,0)) {r=i;break;}
  752.                     }
  753.                     if(r){
  754.                         insert_allocreg(lfg,p,FREEREG,r);
  755.                         lregv[r]=p->z.v;regused[r]=regu[r]=1;
  756.                         if(replace_local_reg(&p->z)!=r){
  757.                             for(i=1;i<=MAXR;i++) if(lregv[i]) printf("%d:%s=%s(%p)\n",i,regnames[i],lregv[i]->identifier,(void*)lregv[i]);
  758.                             ierror(r);}
  759.                         replace_local_reg(&p->q1);
  760.                         if((DEBUG&9216)&&*p->z.v->identifier) printf("temporary <%s> assigned to %s\n",p->z.v->identifier,regnames[r]);
  761.                         if(DEBUG&8192) printf("temporary <%s> assigned to %s\n",p->z.v->identifier,regnames[r]);
  762.                     }
  763.                 }
  764.             }
  765.             if((p->q1.flags&(VAR|REG|VARADR))==VAR&&!(p->q1.v->flags&USEDASADR)&&!(p->q1.v->vtyp->flags&VOLATILE)&&(p->q1.v->storage_class==AUTO||p->q1.v->storage_class==REGISTER)){
  766.                 i=p->q1.v->index;
  767.                 if(BTST(lfg->av_kill,i)&&!BTST(lfg->av_out,i)){
  768.                     t=p->q1.v->vtyp->flags;
  769.                     if(nr&®ok(nr,t,0)&&(!(p->q1.flags&DREFOBJ)||regok(nr,t,p->typf))) r=nr; else r=0;
  770.                     if(p->q1.v->reg){ r=p->q1.v->reg;if(regu[r]) free_hreg(lfg,p,r,1);}
  771.                     for(i=0;r==0&&i<=MAXR;i++){
  772.                         if(!regu[i]&&!regsa[i]&®ok(i,t,0)) {r=i;break;}
  773.                     }
  774.                     if(r){
  775.                         if(r!=nr) insert_allocreg(lfg,p,FREEREG,r);
  776.                             else mustalloc=0;
  777.                         lregv[r]=p->q1.v;regused[r]=regu[r]=1;
  778.                         if(replace_local_reg(&p->q1)!=r) ierror(0);
  779.                         if((DEBUG&9216)&&*p->q1.v->identifier) printf("temporary <%s> assigned to %s\n",p->q1.v->identifier,regnames[r]);
  780.                         if(DEBUG&8192) printf("temporary <%s> assigned to %s\n",p->q1.v->identifier,regnames[r]);
  781.                     }
  782.                 }
  783.             }
  784.             if(p->code==CALL){
  785.                 lfg->calls++;
  786.                 /*  falls Scratchregister bei Funktionsaufruf benutzt   */
  787.                 /*  wird, moeglichst auf ein anderes ausweichen         */
  788.                 for(i=1;i<=MAXR;i++){
  789.                     if(lregv[i]&®scratch[i]&&!lregv[i]->reg)
  790.                         free_hreg(lfg,p,i,0);
  791.                 }
  792.             }
  793.             /*  die Faelle beachten, wenn schon im IC ein Register          */
  794.             /*  angesprochen wird (sollte nur bei CALL und return auftreten */
  795.             if(p->code==FREEREG){
  796.                 ierror(0);
  797.                 if(regu[p->q1.reg]) remove_IC_fg(lfg,p);
  798.                 regu[p->q1.reg]++;
  799.             }
  800.             if(p->code==ALLOCREG){
  801.                 ierror(0);
  802.                 if(regu[p->q1.reg]==2) remove_IC_fg(lfg,p);
  803.                 regu[p->q1.reg]--;
  804.             }
  805.             if(p==lfg->start) i=1; else i=0;;
  806.             p=p->prev;
  807.             if(nr&&mustalloc) insert_allocreg(lfg,p,ALLOCREG,nr);
  808.             if(i) break;
  809.         }
  810.         lfg=lfg->normalout;
  811.     }
  812. }
  813. void insert_saves(void)
  814. /*  fuegt speichern von Registern bei Funktionsaufrufen ein */
  815. {
  816.     int i,c;struct IC *p;
  817.     if(DEBUG&9216) printf("insert_saves\n");
  818.     for(i=1;i<=MAXR;i++) regs[i]=regsa[i];
  819.     for(p=first_ic;p;p=p->next){
  820.         c=p->code;
  821.         if(c==ALLOCREG) regs[p->q1.reg]=1;
  822.         if(c==FREEREG)  regs[p->q1.reg]=0;
  823.         if(c==CALL){
  824.             struct IC *s;
  825.             /*  das Wiederherstellen nach dem GETRETURN     */
  826.             s=p; i=0;
  827.             if(s->next&&s->next->code==FREEREG) {s=s->next;regs[s->q1.reg]=0;}
  828.             if(s->next&&s->next->code==GETRETURN){
  829.                 s=s->next;
  830.                 if((s->z.flags&(REG|DREFOBJ))==REG) i=s->z.reg;
  831.             }
  832.             if(s->next&&s->next->code==ALLOCREG&&s->next->next&&s->next->next->code==GETRETURN){
  833.                 s=s->next->next;
  834.                 if((s->z.flags&(REG|DREFOBJ))==REG) i=s->z.reg;
  835.             }
  836.             savescratch(MOVEFROMREG,p->prev,0);
  837.             savescratch(MOVETOREG,s,i);
  838.         }
  839.     }
  840. }
  841.  
  842. #endif
  843.  
  844. void insert_simple_allocreg(struct IC *p,int code,int reg)
  845. /*  Fuegt ein ALLOCREG/FREEREG (in code) hinter p ein - bei p==0 in */
  846. /*  first_ic.                                                       */
  847. {
  848.     struct IC *new=mymalloc(ICS);
  849.     new->line=0;
  850.     new->file=0;
  851.     regused[reg]=1;
  852.     new->code=code;
  853.     new->typf=0;
  854.     new->q1.am=new->q2.am=new->z.am=0;
  855.     new->q1.flags=REG;
  856.     new->q1.reg=reg;
  857.     new->q2.flags=new->z.flags=0;
  858.     new->use_cnt=new->change_cnt=0;
  859.     new->use_list=new->change_list=0;
  860.     insert_IC(p,new);
  861. }
  862.  
  863. void load_simple_reg_parms(void)
  864. /*  Laedt Registerparameter, falls noetig. Nicht-optimierende Version.  */
  865. {
  866.     int i; struct Var *v;
  867.     for(i=0;i<=1;i++){
  868.         if(i==0) v=merk_varf; else v=first_var[1];
  869.         for(;v;v=v->next){
  870.             if((v->flags®PARM)&®sv[v->reg]!=v){
  871.                 struct IC *new; int j;
  872.                 insert_simple_allocreg(0,FREEREG,v->reg);
  873.                 new=mymalloc(ICS);
  874.                 new->line=0;
  875.                 new->file=0;
  876.                 new->code=ASSIGN;
  877.                 new->typf=v->vtyp->flags;
  878.                 new->q1.flags=REG;
  879.                 new->q1.reg=v->reg;
  880.                 new->q2.flags=0;
  881.                 new->q2.val.vlong=szof(v->vtyp);
  882.                 new->z.flags=VAR;
  883.                 new->z.val.vlong=l2zl(0L);
  884.                 new->z.v=v;
  885.                 for(j=1;j<=MAXR;j++)
  886.                     if(regsv[j]==v){ new->z.flags|=REG;new->z.reg=j;break; }
  887.                 new->q1.am=new->q2.am=new->z.am=0;
  888.                 new->use_cnt=new->change_cnt=0;
  889.                 new->use_list=new->change_list=0;
  890.                 insert_IC(0,new);
  891.                 insert_simple_allocreg(0,ALLOCREG,v->reg);
  892.                 if(new->z.flags®){
  893.                     /*  ALLOCREG verschieben    */
  894.                     struct IC *p;
  895.                     insert_simple_allocreg(0,ALLOCREG,new->z.reg);
  896.                     for(p=new->next;p;p=p->next){
  897.                         if(p->code==ALLOCREG&&p->q1.reg==new->z.reg){
  898.                             remove_IC(p);
  899.                             break;
  900.                         }
  901.                     }
  902.                     if(!p) ierror(0);
  903.                 }
  904.             }
  905.         }
  906.     }
  907. }
  908.  
  909. void simple_regs(void)
  910. /*  haelt Variablen in Registern, simple Version            */
  911. {
  912.     int i2,i,j;int pri;struct Var *v;
  913.     struct IC *icp,*start=first_ic;
  914.     if(!first_ic) return;
  915.     for(i=1;i<=MAXR;i++) regsv[i]=0;
  916.     for(i2=0;i2<=MAXR*4;i2++){
  917.         int only_best,pointertype;
  918.         if(i2<=MAXR*2){i=i2;only_best=1;} else {i=i2/2;pointertype=only_best=0;}
  919.         if(i>MAXR||!regsv[i]){
  920.             if(i>MAXR){
  921.                 i-=MAXR;
  922.                 if(regsv[i]) continue;
  923.             }else{
  924.                 /*  Ziehe Scratchregister vor, wenn kein Funktionsaufruf */
  925.                 /*  erfolgt, sonst erst andere                           */
  926.                 if(!function_calls&&!regscratch[i]) continue;
  927.                 if(function_calls&®scratch[i]) continue;
  928.             }
  929.             if(regused[i]) continue;
  930.             /* Nicht-Scratchregister muessen einmal gesichert und wieder    */
  931.             /* hergestellt werden, Scratchregister bei jedem Call           */
  932.             if(regscratch[i]&&function_calls) continue;
  933.             /*pri=2;*/ pri=0;
  934.             for(j=0;j<=1;j++){
  935.                 if(j==0) v=merk_varf; else v=first_var[1];
  936.                 while(v){
  937.                     if(v->storage_class==AUTO||v->storage_class==REGISTER){
  938.                         if(!(v->flags&USEDASADR)&&!(v->vtyp->flags&VOLATILE)){
  939.                             if(only_best&&v->vtyp->next) pointertype=v->vtyp->next->flags;
  940.                             if(v->priority>pri&®ok(i,v->vtyp->flags&31,pointertype)){
  941.                                 regsv[i]=v;pri=v->priority;
  942.                             }
  943.                         }
  944.                     }
  945.                     v=v->next;
  946.                 }
  947.             }
  948.         }
  949.         if(regsv[i]){
  950.             if(DEBUG&1) printf("Assigned <%s> to %s\n",regsv[i]->identifier,regnames[i]);
  951.             regsv[i]->priority=0;regused[i]=1;
  952.             if(!zlleq(l2zl(0L),regsv[i]->offset)&&!(regsv[i]->flags&CONVPARAMETER)){
  953.                 icp=mymalloc(ICS);
  954.                 icp->line=0;
  955.                 icp->file=0;
  956.                 icp->q1.am=icp->q2.am=icp->z.am=0;
  957.                 icp->code=ASSIGN;
  958.                 icp->typf=regsv[i]->vtyp->flags&31;
  959.                 icp->q1.flags=VAR;
  960.                 icp->q1.v=regsv[i];
  961.                 icp->q1.val.vlong=l2zl(0L);
  962.                 icp->q2.flags=0;
  963.                 icp->q2.val.vlong=szof(regsv[i]->vtyp);
  964.                 icp->z.flags=REG;
  965.                 icp->z.reg=i;
  966.                 icp->next=first_ic;
  967.                 icp->prev=0;
  968.                 first_ic->prev=icp;
  969.                 first_ic=icp;
  970.             }
  971.             icp=mymalloc(ICS);
  972.             icp->line=0;
  973.             icp->file=0;
  974.             icp->q1.am=icp->q2.am=icp->z.am=0;
  975.             icp->code=ALLOCREG;
  976.             icp->q1.flags=REG;
  977.             icp->q1.reg=i;
  978.             icp->q2.flags=icp->z.flags=icp->typf=0;
  979.             icp->next=first_ic;
  980.             icp->prev=0;
  981.             first_ic->prev=icp;
  982.             first_ic=icp;
  983.             icp=mymalloc(ICS);
  984.             icp->q1.am=icp->q2.am=icp->z.am=0;
  985.             icp->code=FREEREG;
  986.             icp->q1.flags=REG;
  987.             icp->q1.reg=i;
  988.             icp->q2.flags=icp->z.flags=icp->typf=0;
  989.             icp->next=0;
  990.             add_IC(icp);
  991.         }
  992.     }
  993.     icp=start;
  994.     while(icp){
  995.         if((icp->code==ALLOCREG||icp->code==FREEREG)&®sv[icp->q1.reg]){
  996.         /*  irgendwelche allocreg/freereg im Code entfernen     */
  997.         /*  sollte nur beim Returnregister vorkommen            */
  998.             struct IC *m=icp->next;
  999.             remove_IC(icp);
  1000.             icp=m;continue;
  1001.         }
  1002.         for(i=1;i<=MAXR;i++){
  1003.             if(!regsv[i]) continue;
  1004.             if((icp->q1.flags&(VAR|DONTREGISTERIZE))==VAR&&icp->q1.v==regsv[i]){
  1005.                 icp->q1.flags|=REG;
  1006.                 icp->q1.reg=i;
  1007.             }
  1008.             if((icp->q2.flags&(VAR|DONTREGISTERIZE))==VAR&&icp->q2.v==regsv[i]){
  1009.                 icp->q2.flags|=REG;
  1010.                 icp->q2.reg=i;
  1011.             }
  1012.             if((icp->z.flags&(VAR|DONTREGISTERIZE))==VAR&&icp->z.v==regsv[i]){
  1013.                 icp->z.flags|=REG;
  1014.                 icp->z.reg=i;
  1015.             }
  1016.         }
  1017.         icp=icp->next;
  1018.     }
  1019. }
  1020.  
  1021.  
  1022.